<?php
/*
 * 上传文件辅助类
 * @author andery <andery@foxmail.com>
 * @link http://www.minophp.com/
 * @version $Id: CUpload.lib.php 2010-05-20 11:41:10Z andery $
 */
class CUpload
{
    // 最后一次的错误代码
    private $_errorcode = 0;
    // 文件保存路径
    private $_rootDir = null;
    // 要上传的文件信息
    private $_file = null;
    // 允许上传的文件类型 为空则表示所有类型
    private $_allowedType = null;
    // 允许上传的文件大小 array('$max', '$least')
    private $_allowedSize = null;
    
    public function __construct()
    {
        
    }
    /**
     * 上传文件
     * @param array $file
     * @param string $dir
     * @param string $name
     * @param string $type
     * @param array $size
     */
    public function save($file, $dir='', $name='', $type='', $size=''){
        CLang::load('lib.Upload');
        if (!$this->_setFile($file)) {
            return false;
        }
        if (!$this->_setRootDir($dir)) {
            return false;
        }
        if (!empty($type)) {
            $this->_setAllowType($type);
            if (!$this->_isAllowType($this->_file['extension'])) {
                return false;
            }
        }
        if (!empty($size)) {
            $this->_setAllowSize($size);
            if (!$this->_isAllowSize($this->_file['size'])) {
                return false;
            }
        }
        return $this->_save($name);
    }
    
    /**
     * 设置需要上传的文件，更新类属性
     * @param array $file
     */
    private function _setFile($file)
    {
        if (is_uploaded_file($file['name'])) {
            $this->_errorcode = 5;
            return false;
        }
        $nameinfo = pathinfo($file['name']);
        $file['extension'] = $nameinfo['extension'];
        $this->_file = $file;
        return true;
    }
    
    private function _setRootDir($dir)
    {
    	if (!is_dir($dir)) {
    	    $this->_errorcode = 7;
    	    return false;
    	}
        $this->_rootDir = $dir;
        return true;
    }
    
    /**
     * 设置允许上传的文件类型
     * @param string $type 文件类型用"|"隔开
     * @return void
     */
    private function _setAllowType($type)
    {
        $this->_allowedType = explode('|', $type);
    }
    
    /**
     * 上传文件大小限制
     * @param array $size
     * @return void
     */
    private function _setAllowSize($size)
    {
        $this->_allowedSize = $size;
    }
       
    public function getMasage()
    {
        if ($this->_errorcode == 0) return false; 
        return CLang::get('upload_error_'.$this->_errorcode);
    }
    
    public function error()
    {
        return $this->_errorcode;
    }
    
    /***
     * 保存文件
     * @param string $name 定义保存文件名
     */
    private function _save($name='')
    {
        if (!$this->_file) {
            $this->_errorcode = 4;
            return false;
        }
        $newname = empty($name) ? $this->_file['name'] : $name.'.'.$this->_file['extension'];
        if ($this->_save_local($this->_rootDir.$newname)) {
            return $newname;
        } else {
            return false;
        }
    }
    
    /**
     * 文件保存到本地
     * @param string $target
     * @return mixed
     */    private function _save_local($target)
    {
        if (move_uploaded_file($this->_file['tmp_name'], $target)) {
            @chmod($target, 0777);
            return true;
        } else {
            $this->_errorcode = 6;
            return false;
        }
    }
    
    /**
     * 检测是否是允许上传的文件类型
     * @param string $type
     * @return bool
     */
    private function _isAllowType($type)
    {
        if (!$this->_allowedType) {
            return true;
        }
        if (!in_array(strtolower($type), $this->_allowedType)) {
            $this->_errorcode = 1;
            return false;
        }
        return true;
    }
    
    /**
     * 检测文件大小是否正确
     * @param array $size
     * @return bool
     */
    private function _isAllowSize($size)
    {
        if ($size < $this->_allowedSize[0]) {
            $this->_errorcode = 2;
            return false;
        }
        if ($size > $this->_allowedSize[1]) {
            $this->_errorcode = 3;
            return false;
        }
        return true;
    }
}